package com.caseprocessing.service;

import com.caseprocessing.model.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 合规性检查器
 * 根据相关法规标准对文书进行合规性检查
 */
public class ComplianceChecker {
    
    private SignatureChecker signatureChecker;
    private DateChecker dateChecker;
    private SealChecker sealChecker;
    private DocumentNumberChecker documentNumberChecker;
    private FormatChecker formatChecker;
    
    public ComplianceChecker() {
        this.signatureChecker = new SignatureChecker();
        this.dateChecker = new DateChecker();
        this.sealChecker = new SealChecker();
        this.documentNumberChecker = new DocumentNumberChecker();
        this.formatChecker = new FormatChecker();
    }
    
    /**
     * 对文档片段进行全面合规性检查
     */
    public ComplianceResult checkDocument(DocumentSegment document) {
        ComplianceResult result = new ComplianceResult();
        result.setSegmentId(document.getSegmentId());
        result.setDocumentType(document.getDocumentType());
        
        // 1. 签名检查
        SignatureCheckResult signatureResult = signatureChecker.checkSignature(document);
        result.setSignatureCheck(signatureResult);
        
        // 2. 日期检查
        DateCheckResult dateResult = dateChecker.checkDate(document);
        result.setDateCheck(dateResult);
        
        // 3. 印章检查
        SealCheckResult sealResult = sealChecker.checkOfficialSeal(document);
        result.setSealCheck(sealResult);
        
        // 4. 文号检查
        DocumentNumberCheckResult docNumberResult = documentNumberChecker.checkDocumentNumber(document);
        result.setDocumentNumberCheck(docNumberResult);
        
        // 5. 格式规范检查
        FormatCheckResult formatResult = formatChecker.checkFormat(document);
        result.setFormatCheck(formatResult);
        
        // 6. 计算综合合规状态
        result.setOverallStatus(calculateOverallStatus(result));
        
        return result;
    }
    
    /**
     * 计算综合合规状态
     */
    private CheckStatus calculateOverallStatus(ComplianceResult result) {
        List<CheckStatus> statuses = Arrays.asList(
            result.getSignatureCheck().getStatus(),
            result.getDateCheck().getStatus(),
            result.getSealCheck().getStatus(),
            result.getDocumentNumberCheck().getStatus(),
            result.getFormatCheck().getStatus()
        );
        
        // 如果有任何FAILED，整体为FAILED
        if (statuses.contains(CheckStatus.FAILED)) {
            return CheckStatus.FAILED;
        }
        
        // 如果有WARNING，整体为WARNING
        if (statuses.contains(CheckStatus.WARNING)) {
            return CheckStatus.WARNING;
        }
        
        // 全部PASSED才为PASSED
        return CheckStatus.PASSED;
    }
    
    /**
     * 签名检查器
     */
    static class SignatureChecker {
        
        public SignatureCheckResult checkSignature(DocumentSegment document) {
            SignatureCheckResult result = new SignatureCheckResult();
            
            // 检查是否需要签名（根据文书类型）
            if (!requiresSignature(document.getDocumentType())) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("该类型文书不需要签名");
                return result;
            }
            
            // 查找签名区域
            List<LayoutElement> signatureAreas = findSignatureAreas(document);
            
            if (signatureAreas.isEmpty()) {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("未发现签名区域");
                result.setConfidence(0.1);
                return result;
            }
            
            // 检查签名有效性
            boolean hasValidSignature = false;
            for (LayoutElement area : signatureAreas) {
                if (area.hasSignature() && isValidSignature(area)) {
                    hasValidSignature = true;
                    break;
                }
            }
            
            if (hasValidSignature) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("发现有效签名");
                result.setConfidence(0.9);
            } else {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("签名区域无有效签名或签名不清晰");
                result.setConfidence(0.3);
            }
            
            return result;
        }
        
        /**
         * 判断文书类型是否需要签名
         */
        private boolean requiresSignature(DocumentType type) {
            return type == DocumentType.CASE_DECISION || 
                   type == DocumentType.NOTIFICATION ||
                   type == DocumentType.REVIEW_OPINION ||
                   type == DocumentType.INVESTIGATION_RECORD;
        }
        
        /**
         * 查找签名区域
         */
        private List<LayoutElement> findSignatureAreas(DocumentSegment document) {
            List<LayoutElement> signatureAreas = new ArrayList<>();
            
            for (Page page : document.getPages()) {
                if (page.getLayoutElements() != null) {
                    for (LayoutElement element : page.getLayoutElements()) {
                        if (element.isSignatureArea()) {
                            signatureAreas.add(element);
                        }
                    }
                }
            }
            
            return signatureAreas;
        }
        
        /**
         * 验证签名有效性
         */
        private boolean isValidSignature(LayoutElement signatureArea) {
            // 检查签名类型
            String signatureType = signatureArea.getSignatureType();
            if (signatureType == null) {
                return false;
            }
            
            // 手写签名和电子签名都认为有效
            return "handwritten".equals(signatureType) || 
                   "electronic".equals(signatureType);
        }
    }
    
    /**
     * 日期检查器
     */
    static class DateChecker {
        
        // DA/T 18-1999标准：8位数字日期格式
        private static final Pattern DATE_PATTERN = Pattern.compile("(\\d{8})");
        
        public DateCheckResult checkDate(DocumentSegment document) {
            DateCheckResult result = new DateCheckResult();
            
            String content = document.getFullText();
            List<String> foundDates = extractDates(content);
            
            if (foundDates.isEmpty()) {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("未发现符合DA/T 18-1999标准的日期格式");
                return result;
            }
            
            // 验证日期逻辑性
            List<String> validDates = new ArrayList<>();
            List<String> invalidDates = new ArrayList<>();
            
            for (String date : foundDates) {
                if (isValidDate(date)) {
                    validDates.add(date);
                } else {
                    invalidDates.add(date);
                }
            }
            
            if (validDates.isEmpty()) {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("发现日期格式但不符合逻辑：" + String.join(", ", invalidDates));
                return result;
            }
            
            // 检查日期一致性
            boolean dateConsistent = checkDateConsistency(document.getDocumentType(), validDates);
            
            if (dateConsistent) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("日期格式和逻辑性检查通过");
                result.setFoundDates(validDates);
            } else {
                result.setStatus(CheckStatus.WARNING);
                result.setMessage("日期格式正确但可能存在逻辑问题");
                result.setFoundDates(validDates);
            }
            
            return result;
        }
        
        /**
         * 提取文档中的日期
         */
        private List<String> extractDates(String content) {
            List<String> dates = new ArrayList<>();
            Matcher matcher = DATE_PATTERN.matcher(content);
            
            while (matcher.find()) {
                dates.add(matcher.group(1));
            }
            
            return dates;
        }
        
        /**
         * 验证日期的逻辑性
         */
        private boolean isValidDate(String dateStr) {
            if (dateStr.length() != 8) return false;
            
            try {
                int year = Integer.parseInt(dateStr.substring(0, 4));
                int month = Integer.parseInt(dateStr.substring(4, 6));
                int day = Integer.parseInt(dateStr.substring(6, 8));
                
                // 基本范围检查
                if (year < 1900 || year > 2030) return false;
                if (month < 1 || month > 12) return false;
                if (day < 1 || day > 31) return false;
                
                // 简单的月份天数检查
                if (month == 2 && day > 29) return false;
                if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return false;
                
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
        
        /**
         * 检查日期一致性
         */
        private boolean checkDateConsistency(DocumentType type, List<String> dates) {
            if (dates.size() <= 1) return true;
            
            // 对于某些文书类型，检查日期的先后顺序
            if (type == DocumentType.CASE_DECISION) {
                // 处罚决定书的日期应该合理
                Collections.sort(dates);
                String earliest = dates.get(0);
                String latest = dates.get(dates.size() - 1);
                
                // 检查日期跨度不应超过合理范围（比如2年）
                return calculateDaysDifference(earliest, latest) <= 730;
            }
            
            return true;
        }
        
        /**
         * 计算两个日期之间的天数差
         */
        private long calculateDaysDifference(String date1, String date2) {
            // 简化计算，实际应该使用日期库
            try {
                int year1 = Integer.parseInt(date1.substring(0, 4));
                int year2 = Integer.parseInt(date2.substring(0, 4));
                return Math.abs((year2 - year1) * 365);
            } catch (Exception e) {
                return 0;
            }
        }
    }
    
    /**
     * 印章检查器
     */
    static class SealChecker {
        
        public SealCheckResult checkOfficialSeal(DocumentSegment document) {
            SealCheckResult result = new SealCheckResult();
            
            // 检查是否需要印章
            if (!requiresSeal(document.getDocumentType())) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("该类型文书不需要印章");
                return result;
            }
            
            // 查找印章区域
            List<LayoutElement> sealAreas = findSealAreas(document);
            
            if (sealAreas.isEmpty()) {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("未发现印章区域");
                return result;
            }
            
            // 检查印章有效性
            boolean hasValidSeal = false;
            for (LayoutElement area : sealAreas) {
                if (area.hasSeal() && isValidSeal(area)) {
                    hasValidSeal = true;
                    break;
                }
            }
            
            if (hasValidSeal) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("发现有效印章");
                result.setConfidence(0.9);
            } else {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("印章区域无有效印章或印章不清晰");
                result.setConfidence(0.3);
            }
            
            return result;
        }
        
        /**
         * 判断文书类型是否需要印章
         */
        private boolean requiresSeal(DocumentType type) {
            return type == DocumentType.CASE_DECISION || 
                   type == DocumentType.NOTIFICATION ||
                   type == DocumentType.REVIEW_OPINION;
        }
        
        /**
         * 查找印章区域
         */
        private List<LayoutElement> findSealAreas(DocumentSegment document) {
            List<LayoutElement> sealAreas = new ArrayList<>();
            
            for (Page page : document.getPages()) {
                if (page.getLayoutElements() != null) {
                    for (LayoutElement element : page.getLayoutElements()) {
                        if (element.isSealArea()) {
                            sealAreas.add(element);
                        }
                    }
                }
            }
            
            return sealAreas;
        }
        
        /**
         * 验证印章有效性
         */
        private boolean isValidSeal(LayoutElement sealArea) {
            String sealType = sealArea.getSealType();
            if (sealType == null) {
                return false;
            }
            
            // 官方印章和电子印章都认为有效
            return "official".equals(sealType) || 
                   "electronic".equals(sealType);
        }
    }
    
    /**
     * 文号检查器
     */
    static class DocumentNumberChecker {
        
        // 常见文号格式：机关名称〔年份〕序号号
        private static final Pattern DOC_NUMBER_PATTERN = 
            Pattern.compile("([\\u4e00-\\u9fa5]+[〔\\[]\\d{4}[〕\\]]\\d+号)");
        
        public DocumentNumberCheckResult checkDocumentNumber(DocumentSegment document) {
            DocumentNumberCheckResult result = new DocumentNumberCheckResult();
            
            // 检查是否需要文号
            if (!requiresDocumentNumber(document.getDocumentType())) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("该类型文书不需要文号");
                return result;
            }
            
            String content = document.getFullText();
            List<String> foundNumbers = extractDocumentNumbers(content);
            
            if (foundNumbers.isEmpty()) {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("未发现符合格式的文号");
                return result;
            }
            
            // 验证文号格式
            boolean hasValidNumber = false;
            for (String number : foundNumbers) {
                if (isValidDocumentNumber(number)) {
                    hasValidNumber = true;
                    result.setFoundNumber(number);
                    break;
                }
            }
            
            if (hasValidNumber) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("文号格式检查通过");
            } else {
                result.setStatus(CheckStatus.WARNING);
                result.setMessage("发现文号但格式可能不规范");
                result.setFoundNumber(foundNumbers.get(0));
            }
            
            return result;
        }
        
        /**
         * 判断文书类型是否需要文号
         */
        private boolean requiresDocumentNumber(DocumentType type) {
            return type == DocumentType.CASE_DECISION || 
                   type == DocumentType.NOTIFICATION ||
                   type == DocumentType.REVIEW_OPINION;
        }
        
        /**
         * 提取文号
         */
        private List<String> extractDocumentNumbers(String content) {
            List<String> numbers = new ArrayList<>();
            Matcher matcher = DOC_NUMBER_PATTERN.matcher(content);
            
            while (matcher.find()) {
                numbers.add(matcher.group(1));
            }
            
            return numbers;
        }
        
        /**
         * 验证文号格式
         */
        private boolean isValidDocumentNumber(String number) {
            // 检查是否包含年份和序号
            return number.matches(".*[〔\\[]\\d{4}[〕\\]]\\d+号.*");
        }
    }
    
    /**
     * 格式检查器
     */
    static class FormatChecker {
        
        public FormatCheckResult checkFormat(DocumentSegment document) {
            FormatCheckResult result = new FormatCheckResult();
            List<String> formatIssues = new ArrayList<>();
            
            // 检查页面规格
            checkPageFormat(document, formatIssues);
            
            // 检查文本密度
            checkTextDensity(document, formatIssues);
            
            // 检查必要元素
            checkRequiredElements(document, formatIssues);
            
            if (formatIssues.isEmpty()) {
                result.setStatus(CheckStatus.PASSED);
                result.setMessage("格式检查通过");
            } else if (formatIssues.size() <= 2) {
                result.setStatus(CheckStatus.WARNING);
                result.setMessage("格式存在轻微问题：" + String.join("; ", formatIssues));
            } else {
                result.setStatus(CheckStatus.FAILED);
                result.setMessage("格式存在重大问题：" + String.join("; ", formatIssues));
            }
            
            result.setFormatIssues(formatIssues);
            return result;
        }
        
        /**
         * 检查页面格式
         */
        private void checkPageFormat(DocumentSegment document, List<String> issues) {
            for (Page page : document.getPages()) {
                if (page.getDimensions() != null) {
                    if (!page.getDimensions().isA4Size()) {
                        issues.add("页面" + page.getPageId() + "尺寸不符合A4标准");
                    }
                }
            }
        }
        
        /**
         * 检查文本密度
         */
        private void checkTextDensity(DocumentSegment document, List<String> issues) {
            for (Page page : document.getPages()) {
                if (page.getPageMetadata() != null) {
                    double textDensity = page.getPageMetadata().getTextDensity();
                    if (textDensity < 0.1) {
                        issues.add("页面" + page.getPageId() + "文本密度过低，可能为空白页");
                    } else if (textDensity > 0.9) {
                        issues.add("页面" + page.getPageId() + "文本密度过高，可能存在版式问题");
                    }
                }
            }
        }
        
        /**
         * 检查必要元素
         */
        private void checkRequiredElements(DocumentSegment document, List<String> issues) {
            DocumentType type = document.getDocumentType();
            
            if (type == DocumentType.CASE_DECISION) {
                String content = document.getFullText();
                
                if (!content.contains("当事人") && !content.contains("被处罚人")) {
                    issues.add("处罚决定书缺少当事人信息");
                }
                
                if (!content.contains("违法行为") && !content.contains("违法事实")) {
                    issues.add("处罚决定书缺少违法行为描述");
                }
                
                if (!content.contains("处罚") && !content.contains("罚款")) {
                    issues.add("处罚决定书缺少处罚内容");
                }
            }
        }
    }
    
    /**
     * 批量检查多个文档片段
     */
    public List<ComplianceResult> checkAllDocuments(List<DocumentSegment> documents) {
        List<ComplianceResult> results = new ArrayList<>();
        
        for (DocumentSegment document : documents) {
            ComplianceResult result = checkDocument(document);
            results.add(result);
        }
        
        return results;
    }
    
    /**
     * 生成合规性检查报告
     */
    public ComplianceReport generateReport(List<ComplianceResult> results) {
        ComplianceReport report = new ComplianceReport();
        
        int passedCount = 0;
        int warningCount = 0;
        int failedCount = 0;
        
        for (ComplianceResult result : results) {
            switch (result.getOverallStatus()) {
                case PASSED: passedCount++; break;
                case WARNING: warningCount++; break;
                case FAILED: failedCount++; break;
            }
        }
        
        report.setTotalDocuments(results.size());
        report.setPassedCount(passedCount);
        report.setWarningCount(warningCount);
        report.setFailedCount(failedCount);
        report.setResults(results);
        
        return report;
    }
}